package com.jwsoft.manager.core.integration.common.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.enums.AccountType;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.bifang.engine.assistant.core.enums.EquipmentTypeEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.assistant.core.exception.AppException;
import com.bifang.module.base.common.enums.ObjectTypeEnum;
import com.bifang.module.base.common.enums.UserAddTypeEnum;
import com.bifang.module.base.common.util.CommonSecureUtil;
import com.bifang.module.base.common.vo.common.CommonVO;
import com.bifang.module.base.common.vo.dict.DictQueryVO;
import com.bifang.module.base.common.vo.dict.SelectVO;
import com.bifang.module.base.common.vo.system.LoginVO;
import com.bifang.module.base.common.vo.system.TokenVO;
import com.bifang.module.base.core.integration.CommonIntegration;
import com.bifang.module.base.core.integration.DictIntegration;
import com.bifang.module.base.core.integration.IndexIntegration;
import com.bifang.module.system.common.enums.CardTypeEnum;
import com.bifang.module.system.common.enums.UserTypeEnum;
import com.bifang.module.system.core.dao.model.SysOrg;
import com.bifang.module.system.core.dao.model.SysUser;
import com.bifang.module.system.core.dao.model.SysUserPrivilege;
import com.bifang.module.system.core.dao.service.SysUserPrivilegeService;
import com.bifang.module.system.core.dao.service.SysUserService;
import com.jwsoft.manager.common.vo.common.XzjhAppVO;
import com.jwsoft.manager.common.vo.common.XzjhPCUserVO;
import com.jwsoft.manager.common.vo.common.XzjhPCVO;
import com.jwsoft.manager.core.dao.model.EduSchool;
import com.jwsoft.manager.core.dao.model.EduSchoolAccount;
import com.jwsoft.manager.core.dao.model.EduXzjhOrg;
import com.jwsoft.manager.core.dao.service.EduSchoolAccountService;
import com.jwsoft.manager.core.dao.service.EduSchoolService;
import com.jwsoft.manager.core.dao.service.EduXzjhOrgService;
import com.jwsoft.manager.core.integration.common.XzjhLoginIntegration;
import com.jwsoft.manager.core.util.XzjhJWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@ApiService(funcCode = "xzjh", title = "学在金华")
@Slf4j
public class XzjhLoginIntegrationImpl implements XzjhLoginIntegration {
    @Autowired
    CommonIntegration commonIntegration;
    @Autowired
    DictIntegration dictIntegration;
    @Autowired
    SysUserService sysUserService;
    @Autowired
    IndexIntegration indexIntegration;
    @Autowired
    EduXzjhOrgService eduXzjhOrgService;
    @Autowired
    SysUserPrivilegeService sysUserPrivilegeService;
    @Autowired
    EduSchoolService eduSchoolService;
    @Autowired
    EduSchoolAccountService eduSchoolAccountService;
    @Override
    @OpApi(funcCode = "xzjh0001", title = "学在金华pc端单点登录", funcType = FuncTypeEnum.query,publicFlag = BoolEnum.TRUE)
    public TokenVO loginPc(XzjhPCVO vo) {
        CommonVO urlVO = new CommonVO();
        urlVO.setParamKey("edu_xzjh_login_pc_url");
        String url = commonIntegration.getValueByKey(urlVO);
        if (StringUtils.isBlank(url)) {
            throw new AppException("请先在系统中配置学在金华PC端单点登录地址：edu_xzjh_login_pc_url");
        }

        CommonVO publicKeyVO = new CommonVO();
        publicKeyVO.setParamKey("edu_xzjh_login_pc_pulbicKey");
        String publicKey = commonIntegration.getValueByKey(publicKeyVO);
        if (StringUtils.isBlank(publicKey)) {
            throw new AppException("请先在系统中配置学在金华PC端单点登录公钥：edu_xzjh_login_pc_pulbicKey");
        }
        vo.setUserType(UserTypeEnum.ADMIN.getType());
        XzjhPCUserVO userVO= null;
        try {
            userVO = XzjhJWTUtil.getUser(vo.getJwt(),publicKey);
        } catch (Exception e) {
            throw new AppException("解析学在金华登录信息失败:"+e.getMessage());
        }

        LoginVO loginVO=new LoginVO();
        if(userVO!=null){
            if(StringUtils.isBlank(userVO.getCellphone())){
                throw new AppException("手机号码不能为空,请先到学在金华维护账号对应手机号码");
            }
            LambdaQueryWrapper<EduSchoolAccount> accountLambdaQueryWrapper=new LambdaQueryWrapper<>();
            accountLambdaQueryWrapper.select(EduSchoolAccount::getOrgId,EduSchoolAccount::getSchoolName).eq(EduSchoolAccount::getPhone,userVO.getCellphone());
            List<EduSchoolAccount> accountList=eduSchoolAccountService.list(accountLambdaQueryWrapper);
            if(CollectionUtils.isEmpty(accountList)){
                throw new AppException("您目前没有权限登录招生系统，请先联系系统管理员添加权限");
            }
            DictQueryVO dictQueryVO = new DictQueryVO();
            dictQueryVO.setUserType(loginVO.getUserType());
            List<String> userTypeList = dictIntegration.getUserTypeList(dictQueryVO);
            loginVO.setCellphone(userVO.getCellphone());
            if(StringUtils.isNotBlank(userVO.getFullName())){
                loginVO.setFullName(userVO.getFullName());
            }else{
                loginVO.setFullName(userVO.getUserName());
            }

            loginVO.setAppId(vo.getAppId());
            loginVO.setUserName(userVO.getUserName());
            loginVO.setReqIp(vo.getReqIp());
            loginVO.setOpenId(userVO.getUserId());
            loginVO.setEquipmentType(EquipmentTypeEnum.PC.getType());
            loginVO.setUserType(vo.getUserType());
            loginVO.setLoginType(AccountType.GOV_OTHER.getKey());
            loginVO.setAddType(UserAddTypeEnum.org.getType());
            if(accountList.size()==1){
                String orgId=accountList.get(0).getOrgId();
                loginVO.setOrgId(orgId);

                //判断账号是否存在，存在则直接登录，学校用户第一次登录创建账号，第二次登录授权，教育局端用户需要手动授权
                EduSchool school=eduSchoolService.getById(loginVO.getOrgId());
                if (school!=null){
                    //学校用户直接授权
                    QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();

                    queryWrapper.lambda().in(SysUser::getUserType, userTypeList).eq(
                            SysUser::getCellphone,
                            CommonSecureUtil.aesEncrypt(loginVO.getCellphone()))
                            .eq(SysUser::getOrgId,orgId);
                    List<SysUser> userList=sysUserService.list(queryWrapper);
                    if(!CollectionUtils.isEmpty(userList)){
                        //判断是否有授权角色，没有的按同类型的设置
                        QueryWrapper<SysUserPrivilege> privilegeQueryWrapper=new QueryWrapper<>();
                        privilegeQueryWrapper.lambda().eq(SysUserPrivilege::getUserId,userList.get(0).getUserId())
                                .eq(SysUserPrivilege::getObjectType, ObjectTypeEnum.role.getType());
                        if(sysUserPrivilegeService.count(privilegeQueryWrapper)<=0){

                            eduXzjhOrgService.upSchoolRole(school.getSchoolCategory(),school.getSchoolNature(),userList.get(0).getUserId());
                        }
                    }
                }

                return indexIntegration.login(loginVO);
            }else{
                List<SelectVO> list=new ArrayList<>();
                for(EduSchoolAccount xzjhOrg:accountList){
                    SelectVO selectVO=new SelectVO();
                    selectVO.setDictValue(xzjhOrg.getSchoolName());
                    selectVO.setDictKey(xzjhOrg.getOrgId());
                    list.add(selectVO);
                    EduSchool school=eduSchoolService.getById(xzjhOrg.getOrgId());
                    if (school!=null){
                        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
                        queryWrapper.lambda().in(SysUser::getUserType, userTypeList).eq(
                                SysUser::getCellphone,
                                CommonSecureUtil.aesEncrypt(loginVO.getCellphone()))
                                .eq(SysUser::getOrgId,xzjhOrg.getOrgId());
                        List<SysUser> userList=sysUserService.list(queryWrapper);
                        if(!CollectionUtils.isEmpty(userList)){
                            //判断是否有授权角色，没有的按同类型的设置
                            QueryWrapper<SysUserPrivilege> privilegeQueryWrapper=new QueryWrapper<>();
                            privilegeQueryWrapper.lambda().eq(SysUserPrivilege::getUserId,userList.get(0).getUserId())
                                    .eq(SysUserPrivilege::getObjectType, ObjectTypeEnum.role.getType());
                            if(sysUserPrivilegeService.count(privilegeQueryWrapper)<=0){
                                eduXzjhOrgService.upSchoolRole(school.getSchoolCategory(),school.getSchoolNature(),userList.get(0).getUserId());
                            }
                        }
                    }
                }

                loginVO.setOrgName(JSON.toJSONString(list));
                //选择学校登录
                throw new AppException(20,"请先选择登录的学校",loginVO);
            }
        }else{
            throw new AppException("未解析到学在金华的用户信息，请先联系学在金华管理");
        }

    }

    @Override
    @OpApi(funcCode = "xzjh0002", title = "学在金华手机端单点登录", funcType = FuncTypeEnum.query,publicFlag = BoolEnum.TRUE)
    public TokenVO loginApp(XzjhAppVO vo) {
        long log1=System.currentTimeMillis();
        if (StringUtils.isBlank(vo.getToken())){
            throw new AppException("请传入token");
        }
        CommonVO appUrl = new CommonVO();
        appUrl.setParamKey("edu_xzjh_login_app_url");
        String url = commonIntegration.getValueByKey(appUrl);
        if (StringUtils.isBlank(url)) {
            throw new AppException("请先在系统中配置学在金华手机端单点登录地址：edu_xzjh_login_app_url");
        }
        Map<String,Object> map=new HashMap<>();
        map.put("token",vo.getToken());
        String params= JSON.toJSONString(map);
        String body = HttpUtil.post(url, params, 10000);
        log.info("学在金华用户信息："+body);
        if (StringUtils.isBlank(body)) {
            throw new AppException("登录失败，学在金华未返回信息");
        }
        long log2=System.currentTimeMillis();
        JSONObject jsonObject = null;
        try {
            jsonObject = JSONObject.parseObject(body);
        } catch (Exception e) {
            throw new AppException("登录失败：" + body);
        }
        Boolean success = jsonObject.getBoolean("success");
        String code=jsonObject.getString("code");
        String msg=jsonObject.getString("message");
        if(success==null ||!success){
            msg=jsonObject.getString("errorMsg");
            throw new AppException("学在金华返回失败："+msg);
        }
        if (StringUtils.isBlank(code)||(Integer.parseInt(code)!=200&&Integer.parseInt(code)!=1)){
            throw new AppException("学在金华返回失败code("+code+"):"+msg);
        }
        JSONObject data=jsonObject.getJSONObject("data");
        LoginVO loginReqVO =new LoginVO();
        String userId=data.getString("userId");//用户中心用户ID
        String userType=data.getString("userType");//家长/学生/教师/普通社会人员
        String username=data.getString("username");//用户中心用户姓名
        String phone=data.getString("phone");//用户中心用户手机
        JSONObject personInfo=data.getJSONObject("personInfo");//浙里办用户信息
        String userIdZlb=personInfo.getString("userId");//浙里办用户主键
        String idTypeZlb=personInfo.getString("idType");//浙里办证件类型
        String usernameZlb=personInfo.getString("userName");//浙里办个人姓名
        String phoneZlb=personInfo.getString("phone");//浙里办手机号
        String idNozlb=personInfo.getString("idNo");//浙里办证件号码

        if(StringUtils.isBlank(idTypeZlb)){
            loginReqVO.setCardType(CardTypeEnum.idcard.getType());
        }else{
            if("1".equals(idTypeZlb)||"ID_CARD".equalsIgnoreCase(idTypeZlb)){
                loginReqVO.setCardType(CardTypeEnum.idcard.getType());
            }else if("2".equals(idTypeZlb)||"PASSPORT".equalsIgnoreCase(idTypeZlb)){
                loginReqVO.setCardType(CardTypeEnum.passport.getType());
            }else if("3".equals(idTypeZlb)||"OFFICER_CARD".equalsIgnoreCase(idTypeZlb)){
                loginReqVO.setCardType(CardTypeEnum.officers.getType());
            }else if("4".equals(idTypeZlb)||"MAINLAND_TRAVEL_PERMIT_FOR_HONGKONG_AND_MACAO_RESIDENTS".equalsIgnoreCase(idTypeZlb)){
                loginReqVO.setCardType(CardTypeEnum.gapermit.getType());
            }else if("5".equals(idTypeZlb)||"MAINLAND_TRAVEL_PERMIT_FOR_TAIWAN_RESIDENTS".equalsIgnoreCase(idTypeZlb)){
                loginReqVO.setCardType(CardTypeEnum.passcheck.getType());
            }else if("6".equals(idTypeZlb)||"FOREIGN_PERMANENT_RESIDENT_ID_CARD".equalsIgnoreCase(idTypeZlb)){
                loginReqVO.setCardType(CardTypeEnum.wgridcard.getType());
            }else{
                loginReqVO.setCardType(CardTypeEnum.other.getType());
            }
        }

        loginReqVO.setIdcard(idNozlb);
        loginReqVO.setFullName(usernameZlb);
        loginReqVO.setCellphone(phoneZlb);
        if(StringUtils.isBlank(vo.getUserType())){
            loginReqVO.setUserType(UserTypeEnum.USER.getType());
        }else{
            loginReqVO.setUserType(vo.getUserType());
        }
        loginReqVO.setAddType(vo.getAddType());
        loginReqVO.setOrgId(vo.getOrgId());
        loginReqVO.setAppId(vo.getAppId());
        loginReqVO.setLoginType(AccountType.ZLB.getKey());
        loginReqVO.setEquipmentType(EquipmentTypeEnum.APP.getType());
        loginReqVO.setOpenId(userIdZlb);//使用浙里办用户id
        TokenVO tokenVO=indexIntegration.login(loginReqVO);
        long log3=System.currentTimeMillis();
        return tokenVO;
    }

    @Override
    @OpApi(funcCode = "xzjh0003", title = "学在金华账号可选择学校", funcType = FuncTypeEnum.query,publicFlag = BoolEnum.TRUE)
    public List<SelectVO> selectOrg(XzjhPCVO vo) {
        if(StringUtils.isBlank(vo.getOrgId())&&CollectionUtils.isEmpty(vo.getOrgIdList())){
            throw new AppException("所属学在东阳单位不能为空");
        }
        QueryWrapper<EduXzjhOrg> orgQueryWrapper=new QueryWrapper<>();
        orgQueryWrapper.lambda().eq(StringUtils.isNotBlank(vo.getOrgId()),EduXzjhOrg::getXzjhOrgId,vo.getOrgId())
                .in(!CollectionUtils.isEmpty(vo.getOrgIdList()),EduXzjhOrg::getXzjhOrgId,vo.getOrgIdList());
        List<EduXzjhOrg> orgs=eduXzjhOrgService.list(orgQueryWrapper);
        if (!CollectionUtils.isEmpty(orgs)){
            List<SelectVO> list=new ArrayList<>();
            for(EduXzjhOrg org:orgs){
                SelectVO selectVO=new SelectVO();
                selectVO.setDictValue(org.getOrgName());
                selectVO.setDictKey(org.getOrgId());
                list.add(selectVO);
            }
            return list;
        }else{
            throw new AppException("未配置对应入学入园学校，请联系系统管理员处理");
        }
    }

    private String getXzjhToken(String url){
        CommonVO appIdVO = new CommonVO();
        appIdVO.setParamKey("edu_xzjh_login_pc_appId");
        String appId = commonIntegration.getValueByKey(appIdVO);
        if (StringUtils.isBlank(appId)) {
            throw new AppException("请先在系统中配置学在金华PC端单点登录appId：edu_xzjh_login_pc_appId");
        }
        CommonVO privateKeyVO = new CommonVO();
        privateKeyVO.setParamKey("edu_xzjh_login_pc_privateKey");
        String privateKey = commonIntegration.getValueByKey(privateKeyVO);
        if (StringUtils.isBlank(privateKey)) {
            throw new AppException("请先在系统中配置学在金华PC端单点登录appId：edu_xzjh_login_pc_appId");
        }
        String path=url+"/oapi/auth/getAccessToken?appKey="+appId+"&appSecret="+privateKey;
        String body=HttpUtil.get(path, 3000);
        if (StringUtils.isBlank(body)) {
            throw new AppException("获取请求token接口，学在金华未返回信息");
        }
        JSONObject jsonObject = null;
        try {
            jsonObject = JSONObject.parseObject(body);
        } catch (Exception e) {
            throw new AppException("获取学在金华请求token接口异常：" + body);
        }
        String code=jsonObject.getString("code");
        String msg=jsonObject.getString("message");
        if (StringUtils.isBlank(code)||(Integer.parseInt(code)!=200&&Integer.parseInt(code)!=1)){
            throw new AppException("学在金华获取token返回失败code("+code+"):"+msg);
        }
        JSONObject data=jsonObject.getJSONObject("data");
        String accessToken=data.getString("accessToken");//token
        return accessToken;
    }
    private List<String> getOrgId(String url,String userId){
        String accessToken=getXzjhToken(url);
        String path=url+"/oapi/uc/detpInfoByUserId?user_id="+userId+"&accessToken="+accessToken;
        String body=HttpUtil.get(path, 3000);
        if (StringUtils.isBlank(body)) {
            throw new AppException("获取学在金华部门信息异常，学在金华未返回信息");
        }
        JSONObject jsonObject = null;
        try {
            jsonObject = JSONObject.parseObject(body);
        } catch (Exception e) {
            throw new AppException("获取学在金华部门信息异常：" + body);
        }
        String code=jsonObject.getString("code");
        String msg=jsonObject.getString("message");
        if (StringUtils.isBlank(code)||(Integer.parseInt(code)!=200&&Integer.parseInt(code)!=1)){
            throw new AppException("获取学在金华部门信息返回失败code("+code+"):"+msg);
        }
        JSONArray array=jsonObject.getJSONArray("data");
        List<String> orgIdList=new ArrayList<>();
        if(array.size()>0){
            for(int i=0;i<array.size();i++){
                JSONObject data=array.getJSONObject(i);
                String orgId=data.getString("org_id");//学校id
                String name=data.getString("name");//学校名称
                orgIdList.add(orgId);
                QueryWrapper<EduXzjhOrg> queryWrapper=new QueryWrapper<>();
                queryWrapper.lambda().eq(EduXzjhOrg::getXzjhOrgId,orgId);
                if(eduXzjhOrgService.count(queryWrapper)<=0){
                    EduXzjhOrg eduXzjhOrg=new EduXzjhOrg();
                    eduXzjhOrg.setXzjhOrgId(orgId);
                    eduXzjhOrg.setXzjhOrgName(name);
                    if (StringUtils.isNotBlank(name)){
                        QueryWrapper<EduSchool> schoolQueryWrapper=new QueryWrapper<>();
                        schoolQueryWrapper.lambda().eq(EduSchool::getSchoolName,name);
                        EduSchool eduSchool=eduSchoolService.getOne(schoolQueryWrapper,false);
                        if (eduSchool!=null){
                            eduXzjhOrg.setOrgId(eduSchool.getOrgId());
                            eduXzjhOrg.setOrgName(eduSchool.getSchoolName());
                            eduXzjhOrgService.save(eduXzjhOrg);
                        }
                    }
                }
            }

            return orgIdList;
        }else{
            throw new AppException("该账号学在金华未配置所属单位或部门，请联系学在金华管理人员配置");
        }

    }
}
